{
 "cells": [
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f54a53b3-862f-45d1-8a50-b659dad18199",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 2,
   "id": "ea3ee0fe-d7fe-4fce-9630-a8e106dc35ee",
   "metadata": {},
   "outputs": [],
   "source": [
    "import pandas as pd\n",
    "import numpy as np\n",
    "\n",
    "np.random.seed(42)\n",
    "n_vehicles = 1000\n",
    "n_days = 30\n",
    "records_per_day = 100\n",
    "\n",
    "# === 时间戳生成（修复版）===\n",
    "dates = pd.date_range(\"2023-06-01\", periods=n_days, freq='D').to_numpy()\n",
    "time_offsets = np.linspace(0, 24*3600*1e9, records_per_day, endpoint=False)\n",
    "daily_timestamps = dates[:, np.newaxis] + time_offsets.astype('timedelta64[ns]')\n",
    "timestamps = np.tile(daily_timestamps.ravel(), n_vehicles)\n",
    "\n",
    "# === 创建数据集 ===\n",
    "data = pd.DataFrame({\n",
    "    \"vehicle_id\": np.repeat(np.arange(n_vehicles), n_days * records_per_day),\n",
    "    \"timestamp\": timestamps,\n",
    "    \"speed\": np.clip(np.random.normal(70, 20, n_vehicles * n_days * records_per_day), 0, 120),\n",
    "    \"acceleration\": np.random.normal(0, 1.5, n_vehicles * n_days * records_per_day),\n",
    "    \"braking\": np.random.exponential(0.3, n_vehicles * n_days * records_per_day),\n",
    "    \"steering_angle\": np.random.normal(0, 12, n_vehicles * n_days * records_per_day),\n",
    "    \"engine_rpm\": np.random.normal(2000, 500, n_vehicles * n_days * records_per_day),\n",
    "    \"fuel_consumption\": np.random.uniform(25, 35, n_vehicles * n_days * records_per_day),\n",
    "    \"gps_lat\": np.random.uniform(39.8, 40.0, n_vehicles * n_days * records_per_day),\n",
    "    \"gps_lon\": np.random.uniform(116.3, 116.5, n_vehicles * n_days * records_per_day),\n",
    "})\n"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 3,
   "id": "5f5da7b5-f1f6-4c6a-94f4-1d4d0b9021c5",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>vehicle_id</th>\n",
       "      <th>timestamp</th>\n",
       "      <th>speed</th>\n",
       "      <th>acceleration</th>\n",
       "      <th>braking</th>\n",
       "      <th>steering_angle</th>\n",
       "      <th>engine_rpm</th>\n",
       "      <th>fuel_consumption</th>\n",
       "      <th>gps_lat</th>\n",
       "      <th>gps_lon</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>2023-06-01 00:00:00</td>\n",
       "      <td>79.934283</td>\n",
       "      <td>-1.660740</td>\n",
       "      <td>0.130730</td>\n",
       "      <td>-1.378481</td>\n",
       "      <td>2076.809543</td>\n",
       "      <td>31.476238</td>\n",
       "      <td>39.994931</td>\n",
       "      <td>116.487207</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>2023-06-01 00:14:24</td>\n",
       "      <td>67.234714</td>\n",
       "      <td>-2.654043</td>\n",
       "      <td>0.214670</td>\n",
       "      <td>12.613769</td>\n",
       "      <td>2291.189140</td>\n",
       "      <td>30.355638</td>\n",
       "      <td>39.964724</td>\n",
       "      <td>116.341567</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>0</td>\n",
       "      <td>2023-06-01 00:28:48</td>\n",
       "      <td>82.953771</td>\n",
       "      <td>-0.506712</td>\n",
       "      <td>1.621234</td>\n",
       "      <td>10.515975</td>\n",
       "      <td>2764.823273</td>\n",
       "      <td>32.651135</td>\n",
       "      <td>39.932167</td>\n",
       "      <td>116.470873</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>2023-06-01 00:43:12</td>\n",
       "      <td>100.460597</td>\n",
       "      <td>0.753567</td>\n",
       "      <td>0.001968</td>\n",
       "      <td>7.864647</td>\n",
       "      <td>2215.282192</td>\n",
       "      <td>27.623160</td>\n",
       "      <td>39.834435</td>\n",
       "      <td>116.483333</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>2023-06-01 00:57:36</td>\n",
       "      <td>65.316933</td>\n",
       "      <td>0.665255</td>\n",
       "      <td>0.262237</td>\n",
       "      <td>7.455299</td>\n",
       "      <td>1937.870214</td>\n",
       "      <td>30.161314</td>\n",
       "      <td>39.805429</td>\n",
       "      <td>116.392046</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2999995</th>\n",
       "      <td>999</td>\n",
       "      <td>2023-06-30 22:48:00</td>\n",
       "      <td>90.931738</td>\n",
       "      <td>0.852453</td>\n",
       "      <td>0.130170</td>\n",
       "      <td>17.197138</td>\n",
       "      <td>2190.655646</td>\n",
       "      <td>31.646072</td>\n",
       "      <td>39.816401</td>\n",
       "      <td>116.351744</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2999996</th>\n",
       "      <td>999</td>\n",
       "      <td>2023-06-30 23:02:24</td>\n",
       "      <td>65.388746</td>\n",
       "      <td>-0.354445</td>\n",
       "      <td>0.852436</td>\n",
       "      <td>7.585394</td>\n",
       "      <td>2317.456054</td>\n",
       "      <td>27.957631</td>\n",
       "      <td>39.982609</td>\n",
       "      <td>116.308104</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2999997</th>\n",
       "      <td>999</td>\n",
       "      <td>2023-06-30 23:16:48</td>\n",
       "      <td>70.234033</td>\n",
       "      <td>-1.682727</td>\n",
       "      <td>0.497367</td>\n",
       "      <td>10.678253</td>\n",
       "      <td>3294.723629</td>\n",
       "      <td>28.096998</td>\n",
       "      <td>39.810707</td>\n",
       "      <td>116.406486</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2999998</th>\n",
       "      <td>999</td>\n",
       "      <td>2023-06-30 23:31:12</td>\n",
       "      <td>80.009523</td>\n",
       "      <td>2.809169</td>\n",
       "      <td>0.582067</td>\n",
       "      <td>14.956755</td>\n",
       "      <td>1301.773268</td>\n",
       "      <td>34.107563</td>\n",
       "      <td>39.876913</td>\n",
       "      <td>116.398760</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2999999</th>\n",
       "      <td>999</td>\n",
       "      <td>2023-06-30 23:45:36</td>\n",
       "      <td>69.296607</td>\n",
       "      <td>-0.038995</td>\n",
       "      <td>0.131680</td>\n",
       "      <td>-23.390794</td>\n",
       "      <td>2257.058028</td>\n",
       "      <td>31.831511</td>\n",
       "      <td>39.845798</td>\n",
       "      <td>116.417981</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>3000000 rows × 10 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "         vehicle_id           timestamp       speed  acceleration   braking  \\\n",
       "0                 0 2023-06-01 00:00:00   79.934283     -1.660740  0.130730   \n",
       "1                 0 2023-06-01 00:14:24   67.234714     -2.654043  0.214670   \n",
       "2                 0 2023-06-01 00:28:48   82.953771     -0.506712  1.621234   \n",
       "3                 0 2023-06-01 00:43:12  100.460597      0.753567  0.001968   \n",
       "4                 0 2023-06-01 00:57:36   65.316933      0.665255  0.262237   \n",
       "...             ...                 ...         ...           ...       ...   \n",
       "2999995         999 2023-06-30 22:48:00   90.931738      0.852453  0.130170   \n",
       "2999996         999 2023-06-30 23:02:24   65.388746     -0.354445  0.852436   \n",
       "2999997         999 2023-06-30 23:16:48   70.234033     -1.682727  0.497367   \n",
       "2999998         999 2023-06-30 23:31:12   80.009523      2.809169  0.582067   \n",
       "2999999         999 2023-06-30 23:45:36   69.296607     -0.038995  0.131680   \n",
       "\n",
       "         steering_angle   engine_rpm  fuel_consumption    gps_lat     gps_lon  \n",
       "0             -1.378481  2076.809543         31.476238  39.994931  116.487207  \n",
       "1             12.613769  2291.189140         30.355638  39.964724  116.341567  \n",
       "2             10.515975  2764.823273         32.651135  39.932167  116.470873  \n",
       "3              7.864647  2215.282192         27.623160  39.834435  116.483333  \n",
       "4              7.455299  1937.870214         30.161314  39.805429  116.392046  \n",
       "...                 ...          ...               ...        ...         ...  \n",
       "2999995       17.197138  2190.655646         31.646072  39.816401  116.351744  \n",
       "2999996        7.585394  2317.456054         27.957631  39.982609  116.308104  \n",
       "2999997       10.678253  3294.723629         28.096998  39.810707  116.406486  \n",
       "2999998       14.956755  1301.773268         34.107563  39.876913  116.398760  \n",
       "2999999      -23.390794  2257.058028         31.831511  39.845798  116.417981  \n",
       "\n",
       "[3000000 rows x 10 columns]"
      ]
     },
     "execution_count": 3,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 4,
   "id": "73e7d87d-e6f2-448c-a12f-16d9e2cb0059",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 添加时间特征\n",
    "data[\"hour\"] = data[\"timestamp\"].dt.hour\n",
    "data[\"is_night\"] = ((data[\"hour\"] >= 22) | (data[\"hour\"] <= 6)).astype(int)\n",
    "data[\"is_peak\"] = ((data[\"hour\"] >= 7) & (data[\"hour\"] <= 9)) | ((data[\"hour\"] >= 17) & (data[\"hour\"] <= 19))"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 5,
   "id": "1e4382e0-07cc-460c-988e-16640724336c",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 添加道路类型特征 (模拟)\n",
    "road_types = [\"高速\", \"国道\", \"城市道路\", \"乡村道路\"]\n",
    "data[\"road_type\"] = np.random.choice(road_types, size=len(data), p=[0.4, 0.3, 0.2, 0.1])"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 6,
   "id": "872a251b-041a-4978-806b-94dd8cff7028",
   "metadata": {},
   "outputs": [],
   "source": [
    "# 数据清洗 - 移除异常值\n",
    "data = data[(data[\"speed\"] > 10) & (data[\"speed\"] < 120)]  # 合理速度范围\n",
    "data = data[data[\"braking\"] < 1.0]  # 合理刹车力度\n",
    "data = data[data[\"fuel_consumption\"] < 40]  # 合理油耗范围"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 7,
   "id": "69000bc1-7f33-4a47-a803-e16dec25633e",
   "metadata": {},
   "outputs": [],
   "source": [
    "# ========== 驾驶行为分析 ==========\n",
    "def detect_risky_events(df):\n",
    "    \"\"\"识别高风险驾驶事件\"\"\"\n",
    "    # 超速检测 (根据道路类型设定不同限速)\n",
    "    speed_limits = {\"高速\": 100, \"国道\": 80, \"城市道路\": 60, \"乡村道路\": 70}\n",
    "    df[\"speed_limit\"] = df[\"road_type\"].map(speed_limits)\n",
    "    df[\"is_overspeed\"] = (df[\"speed\"] > df[\"speed_limit\"]).astype(int)\n",
    "    \n",
    "    # 急刹车检测\n",
    "    df[\"is_hard_brake\"] = (df[\"braking\"] > 0.7).astype(int)\n",
    "    \n",
    "    # 急转弯检测\n",
    "    df[\"is_sharp_turn\"] = (np.abs(df[\"steering_angle\"]) > 30).astype(int)\n",
    "    \n",
    "    # 疲劳驾驶检测 (连续驾驶超过4小时)\n",
    "    df[\"driving_duration\"] = df.groupby(\"vehicle_id\")[\"timestamp\"].diff().dt.total_seconds() / 3600\n",
    "    df[\"is_fatigue\"] = (df.groupby(\"vehicle_id\")[\"driving_duration\"].cumsum() > 4).astype(int)\n",
    "    \n",
    "    # 高风险时间驾驶\n",
    "    df[\"is_high_risk_time\"] = (df[\"is_night\"] | df[\"is_peak\"]).astype(int)\n",
    "    \n",
    "    return df\n",
    "\n",
    "# 执行风险事件检测\n",
    "data = detect_risky_events(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 8,
   "id": "18e2dd90-5e45-4d7e-97d1-9a03a15bade9",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>vehicle_id</th>\n",
       "      <th>timestamp</th>\n",
       "      <th>speed</th>\n",
       "      <th>acceleration</th>\n",
       "      <th>braking</th>\n",
       "      <th>steering_angle</th>\n",
       "      <th>engine_rpm</th>\n",
       "      <th>fuel_consumption</th>\n",
       "      <th>gps_lat</th>\n",
       "      <th>gps_lon</th>\n",
       "      <th>...</th>\n",
       "      <th>is_night</th>\n",
       "      <th>is_peak</th>\n",
       "      <th>road_type</th>\n",
       "      <th>speed_limit</th>\n",
       "      <th>is_overspeed</th>\n",
       "      <th>is_hard_brake</th>\n",
       "      <th>is_sharp_turn</th>\n",
       "      <th>driving_duration</th>\n",
       "      <th>is_fatigue</th>\n",
       "      <th>is_high_risk_time</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>2023-06-01 00:00:00</td>\n",
       "      <td>79.934283</td>\n",
       "      <td>-1.660740</td>\n",
       "      <td>0.130730</td>\n",
       "      <td>-1.378481</td>\n",
       "      <td>2076.809543</td>\n",
       "      <td>31.476238</td>\n",
       "      <td>39.994931</td>\n",
       "      <td>116.487207</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>高速</td>\n",
       "      <td>100</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>NaN</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>0</td>\n",
       "      <td>2023-06-01 00:14:24</td>\n",
       "      <td>67.234714</td>\n",
       "      <td>-2.654043</td>\n",
       "      <td>0.214670</td>\n",
       "      <td>12.613769</td>\n",
       "      <td>2291.189140</td>\n",
       "      <td>30.355638</td>\n",
       "      <td>39.964724</td>\n",
       "      <td>116.341567</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>城市道路</td>\n",
       "      <td>60</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.24</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>0</td>\n",
       "      <td>2023-06-01 00:43:12</td>\n",
       "      <td>100.460597</td>\n",
       "      <td>0.753567</td>\n",
       "      <td>0.001968</td>\n",
       "      <td>7.864647</td>\n",
       "      <td>2215.282192</td>\n",
       "      <td>27.623160</td>\n",
       "      <td>39.834435</td>\n",
       "      <td>116.483333</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>城市道路</td>\n",
       "      <td>60</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.48</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>0</td>\n",
       "      <td>2023-06-01 00:57:36</td>\n",
       "      <td>65.316933</td>\n",
       "      <td>0.665255</td>\n",
       "      <td>0.262237</td>\n",
       "      <td>7.455299</td>\n",
       "      <td>1937.870214</td>\n",
       "      <td>30.161314</td>\n",
       "      <td>39.805429</td>\n",
       "      <td>116.392046</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>高速</td>\n",
       "      <td>100</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.24</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>5</th>\n",
       "      <td>0</td>\n",
       "      <td>2023-06-01 01:12:00</td>\n",
       "      <td>65.317261</td>\n",
       "      <td>-0.759969</td>\n",
       "      <td>0.413655</td>\n",
       "      <td>10.021363</td>\n",
       "      <td>1246.970281</td>\n",
       "      <td>25.631298</td>\n",
       "      <td>39.908541</td>\n",
       "      <td>116.466800</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>高速</td>\n",
       "      <td>100</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.24</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2999995</th>\n",
       "      <td>999</td>\n",
       "      <td>2023-06-30 22:48:00</td>\n",
       "      <td>90.931738</td>\n",
       "      <td>0.852453</td>\n",
       "      <td>0.130170</td>\n",
       "      <td>17.197138</td>\n",
       "      <td>2190.655646</td>\n",
       "      <td>31.646072</td>\n",
       "      <td>39.816401</td>\n",
       "      <td>116.351744</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>国道</td>\n",
       "      <td>80</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.24</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2999996</th>\n",
       "      <td>999</td>\n",
       "      <td>2023-06-30 23:02:24</td>\n",
       "      <td>65.388746</td>\n",
       "      <td>-0.354445</td>\n",
       "      <td>0.852436</td>\n",
       "      <td>7.585394</td>\n",
       "      <td>2317.456054</td>\n",
       "      <td>27.957631</td>\n",
       "      <td>39.982609</td>\n",
       "      <td>116.308104</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>高速</td>\n",
       "      <td>100</td>\n",
       "      <td>0</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0.24</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2999997</th>\n",
       "      <td>999</td>\n",
       "      <td>2023-06-30 23:16:48</td>\n",
       "      <td>70.234033</td>\n",
       "      <td>-1.682727</td>\n",
       "      <td>0.497367</td>\n",
       "      <td>10.678253</td>\n",
       "      <td>3294.723629</td>\n",
       "      <td>28.096998</td>\n",
       "      <td>39.810707</td>\n",
       "      <td>116.406486</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>乡村道路</td>\n",
       "      <td>70</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.24</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2999998</th>\n",
       "      <td>999</td>\n",
       "      <td>2023-06-30 23:31:12</td>\n",
       "      <td>80.009523</td>\n",
       "      <td>2.809169</td>\n",
       "      <td>0.582067</td>\n",
       "      <td>14.956755</td>\n",
       "      <td>1301.773268</td>\n",
       "      <td>34.107563</td>\n",
       "      <td>39.876913</td>\n",
       "      <td>116.398760</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>城市道路</td>\n",
       "      <td>60</td>\n",
       "      <td>1</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.24</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2999999</th>\n",
       "      <td>999</td>\n",
       "      <td>2023-06-30 23:45:36</td>\n",
       "      <td>69.296607</td>\n",
       "      <td>-0.038995</td>\n",
       "      <td>0.131680</td>\n",
       "      <td>-23.390794</td>\n",
       "      <td>2257.058028</td>\n",
       "      <td>31.831511</td>\n",
       "      <td>39.845798</td>\n",
       "      <td>116.417981</td>\n",
       "      <td>...</td>\n",
       "      <td>1</td>\n",
       "      <td>False</td>\n",
       "      <td>国道</td>\n",
       "      <td>80</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0</td>\n",
       "      <td>0.24</td>\n",
       "      <td>1</td>\n",
       "      <td>1</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>2871183 rows × 21 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "         vehicle_id           timestamp       speed  acceleration   braking  \\\n",
       "0                 0 2023-06-01 00:00:00   79.934283     -1.660740  0.130730   \n",
       "1                 0 2023-06-01 00:14:24   67.234714     -2.654043  0.214670   \n",
       "3                 0 2023-06-01 00:43:12  100.460597      0.753567  0.001968   \n",
       "4                 0 2023-06-01 00:57:36   65.316933      0.665255  0.262237   \n",
       "5                 0 2023-06-01 01:12:00   65.317261     -0.759969  0.413655   \n",
       "...             ...                 ...         ...           ...       ...   \n",
       "2999995         999 2023-06-30 22:48:00   90.931738      0.852453  0.130170   \n",
       "2999996         999 2023-06-30 23:02:24   65.388746     -0.354445  0.852436   \n",
       "2999997         999 2023-06-30 23:16:48   70.234033     -1.682727  0.497367   \n",
       "2999998         999 2023-06-30 23:31:12   80.009523      2.809169  0.582067   \n",
       "2999999         999 2023-06-30 23:45:36   69.296607     -0.038995  0.131680   \n",
       "\n",
       "         steering_angle   engine_rpm  fuel_consumption    gps_lat     gps_lon  \\\n",
       "0             -1.378481  2076.809543         31.476238  39.994931  116.487207   \n",
       "1             12.613769  2291.189140         30.355638  39.964724  116.341567   \n",
       "3              7.864647  2215.282192         27.623160  39.834435  116.483333   \n",
       "4              7.455299  1937.870214         30.161314  39.805429  116.392046   \n",
       "5             10.021363  1246.970281         25.631298  39.908541  116.466800   \n",
       "...                 ...          ...               ...        ...         ...   \n",
       "2999995       17.197138  2190.655646         31.646072  39.816401  116.351744   \n",
       "2999996        7.585394  2317.456054         27.957631  39.982609  116.308104   \n",
       "2999997       10.678253  3294.723629         28.096998  39.810707  116.406486   \n",
       "2999998       14.956755  1301.773268         34.107563  39.876913  116.398760   \n",
       "2999999      -23.390794  2257.058028         31.831511  39.845798  116.417981   \n",
       "\n",
       "         ...  is_night  is_peak  road_type speed_limit  is_overspeed  \\\n",
       "0        ...         1    False         高速         100             0   \n",
       "1        ...         1    False       城市道路          60             1   \n",
       "3        ...         1    False       城市道路          60             1   \n",
       "4        ...         1    False         高速         100             0   \n",
       "5        ...         1    False         高速         100             0   \n",
       "...      ...       ...      ...        ...         ...           ...   \n",
       "2999995  ...         1    False         国道          80             1   \n",
       "2999996  ...         1    False         高速         100             0   \n",
       "2999997  ...         1    False       乡村道路          70             1   \n",
       "2999998  ...         1    False       城市道路          60             1   \n",
       "2999999  ...         1    False         国道          80             0   \n",
       "\n",
       "         is_hard_brake  is_sharp_turn  driving_duration  is_fatigue  \\\n",
       "0                    0              0               NaN           0   \n",
       "1                    0              0              0.24           0   \n",
       "3                    0              0              0.48           0   \n",
       "4                    0              0              0.24           0   \n",
       "5                    0              0              0.24           0   \n",
       "...                ...            ...               ...         ...   \n",
       "2999995              0              0              0.24           1   \n",
       "2999996              1              0              0.24           1   \n",
       "2999997              0              0              0.24           1   \n",
       "2999998              0              0              0.24           1   \n",
       "2999999              0              0              0.24           1   \n",
       "\n",
       "         is_high_risk_time  \n",
       "0                        1  \n",
       "1                        1  \n",
       "3                        1  \n",
       "4                        1  \n",
       "5                        1  \n",
       "...                    ...  \n",
       "2999995                  1  \n",
       "2999996                  1  \n",
       "2999997                  1  \n",
       "2999998                  1  \n",
       "2999999                  1  \n",
       "\n",
       "[2871183 rows x 21 columns]"
      ]
     },
     "execution_count": 8,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f8d46640-60a7-4e18-8a0b-44400a143ae5",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 12,
   "id": "1c9a9e83-8198-4d75-a240-e4fe86acf7b9",
   "metadata": {},
   "outputs": [],
   "source": [
    "\n",
    "# ========== 驾驶员评分系统 ==========\n",
    "def calculate_driver_score(df):\n",
    "    \"\"\"计算驾驶员安全评分 (0-100分)\"\"\"\n",
    "    # 聚合车辆级统计数据\n",
    "    driver_stats = df.groupby(\"vehicle_id\").agg(\n",
    "        total_distance=(\"speed\", lambda x: (x * 1/60).sum()),  # 假设每条记录间隔1分钟\n",
    "        overspeed_rate=(\"is_overspeed\", \"mean\"),\n",
    "        hard_brake_count=(\"is_hard_brake\", \"sum\"),\n",
    "        sharp_turn_count=(\"is_sharp_turn\", \"sum\"),\n",
    "        fatigue_hours=(\"is_fatigue\", \"sum\"),  # * 1/60,  # 转换为小时\n",
    "        high_risk_time_ratio=(\"is_high_risk_time\", \"mean\")\n",
    "    ).reset_index()\n",
    "\n",
    "    # print(driver_stats.columns.tolist())\n",
    "    \n",
    "    # 计算各项得分 (每项满分20分)\n",
    "    driver_stats[\"speed_score\"] = np.clip(20 - driver_stats[\"overspeed_rate\"] * 200, 0, 20)\n",
    "    driver_stats[\"brake_score\"] = np.clip(20 - driver_stats[\"hard_brake_count\"] / driver_stats[\"total_distance\"] * 100, 0, 20)\n",
    "    driver_stats[\"turn_score\"] = np.clip(20 - driver_stats[\"sharp_turn_count\"] / driver_stats[\"total_distance\"] * 50, 0, 20)\n",
    "    driver_stats[\"fatigue_score\"] = np.clip(20 - driver_stats[\"fatigue_hours\"] * 2, 0, 20)\n",
    "    driver_stats[\"time_score\"] = np.clip(20 - driver_stats[\"high_risk_time_ratio\"] * 40, 0, 20)\n",
    "    driver_stats[\"fatigue_hours\"] = driver_stats[\"fatigue_hours\"] * 1/60\n",
    "    \n",
    "    # 计算总分\n",
    "    driver_stats[\"driver_score\"] = (\n",
    "        driver_stats[\"speed_score\"] +\n",
    "        driver_stats[\"brake_score\"] +\n",
    "        driver_stats[\"turn_score\"] +\n",
    "        driver_stats[\"fatigue_score\"] +\n",
    "        driver_stats[\"time_score\"]\n",
    "    )\n",
    "    \n",
    "    # 添加评级 (A-D)\n",
    "    bins = [0, 60, 75, 85, 101]\n",
    "    labels = ['D', 'C', 'B', 'A']\n",
    "    driver_stats[\"risk_rating\"] = pd.cut(driver_stats[\"driver_score\"], bins=bins, labels=labels)\n",
    "    \n",
    "    return driver_stats\n",
    "\n",
    "# 计算驾驶员评分\n",
    "driver_scores = calculate_driver_score(data)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": 13,
   "id": "94a85764-6401-4776-913f-0c78490c54db",
   "metadata": {},
   "outputs": [
    {
     "data": {
      "text/html": [
       "<div>\n",
       "<style scoped>\n",
       "    .dataframe tbody tr th:only-of-type {\n",
       "        vertical-align: middle;\n",
       "    }\n",
       "\n",
       "    .dataframe tbody tr th {\n",
       "        vertical-align: top;\n",
       "    }\n",
       "\n",
       "    .dataframe thead th {\n",
       "        text-align: right;\n",
       "    }\n",
       "</style>\n",
       "<table border=\"1\" class=\"dataframe\">\n",
       "  <thead>\n",
       "    <tr style=\"text-align: right;\">\n",
       "      <th></th>\n",
       "      <th>vehicle_id</th>\n",
       "      <th>total_distance</th>\n",
       "      <th>overspeed_rate</th>\n",
       "      <th>hard_brake_count</th>\n",
       "      <th>sharp_turn_count</th>\n",
       "      <th>fatigue_hours</th>\n",
       "      <th>high_risk_time_ratio</th>\n",
       "      <th>speed_score</th>\n",
       "      <th>brake_score</th>\n",
       "      <th>turn_score</th>\n",
       "      <th>fatigue_score</th>\n",
       "      <th>time_score</th>\n",
       "      <th>driver_score</th>\n",
       "      <th>risk_rating</th>\n",
       "    </tr>\n",
       "  </thead>\n",
       "  <tbody>\n",
       "    <tr>\n",
       "      <th>0</th>\n",
       "      <td>0</td>\n",
       "      <td>3386.560282</td>\n",
       "      <td>0.309474</td>\n",
       "      <td>196</td>\n",
       "      <td>38</td>\n",
       "      <td>47.933333</td>\n",
       "      <td>0.629668</td>\n",
       "      <td>0.0</td>\n",
       "      <td>14.212417</td>\n",
       "      <td>19.438959</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>33.651375</td>\n",
       "      <td>D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>1</th>\n",
       "      <td>1</td>\n",
       "      <td>3309.030614</td>\n",
       "      <td>0.291117</td>\n",
       "      <td>185</td>\n",
       "      <td>30</td>\n",
       "      <td>47.766667</td>\n",
       "      <td>0.631506</td>\n",
       "      <td>0.0</td>\n",
       "      <td>14.409239</td>\n",
       "      <td>19.546695</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>33.955934</td>\n",
       "      <td>D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>2</th>\n",
       "      <td>2</td>\n",
       "      <td>3331.436376</td>\n",
       "      <td>0.305410</td>\n",
       "      <td>214</td>\n",
       "      <td>29</td>\n",
       "      <td>47.466667</td>\n",
       "      <td>0.627923</td>\n",
       "      <td>0.0</td>\n",
       "      <td>13.576344</td>\n",
       "      <td>19.564752</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>33.141097</td>\n",
       "      <td>D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>3</th>\n",
       "      <td>3</td>\n",
       "      <td>3336.086285</td>\n",
       "      <td>0.295936</td>\n",
       "      <td>166</td>\n",
       "      <td>36</td>\n",
       "      <td>47.733333</td>\n",
       "      <td>0.628691</td>\n",
       "      <td>0.0</td>\n",
       "      <td>15.024110</td>\n",
       "      <td>19.460446</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>34.484555</td>\n",
       "      <td>D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>4</th>\n",
       "      <td>4</td>\n",
       "      <td>3393.379616</td>\n",
       "      <td>0.314207</td>\n",
       "      <td>182</td>\n",
       "      <td>29</td>\n",
       "      <td>47.933333</td>\n",
       "      <td>0.630833</td>\n",
       "      <td>0.0</td>\n",
       "      <td>14.636615</td>\n",
       "      <td>19.572697</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>34.209313</td>\n",
       "      <td>D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>...</th>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "      <td>...</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>995</th>\n",
       "      <td>995</td>\n",
       "      <td>3342.214145</td>\n",
       "      <td>0.292029</td>\n",
       "      <td>179</td>\n",
       "      <td>35</td>\n",
       "      <td>47.600000</td>\n",
       "      <td>0.633484</td>\n",
       "      <td>0.0</td>\n",
       "      <td>14.644269</td>\n",
       "      <td>19.476395</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>34.120664</td>\n",
       "      <td>D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>996</th>\n",
       "      <td>996</td>\n",
       "      <td>3356.451499</td>\n",
       "      <td>0.299166</td>\n",
       "      <td>178</td>\n",
       "      <td>41</td>\n",
       "      <td>47.700000</td>\n",
       "      <td>0.630299</td>\n",
       "      <td>0.0</td>\n",
       "      <td>14.696780</td>\n",
       "      <td>19.389236</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>34.086016</td>\n",
       "      <td>D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>997</th>\n",
       "      <td>997</td>\n",
       "      <td>3344.071826</td>\n",
       "      <td>0.310453</td>\n",
       "      <td>167</td>\n",
       "      <td>37</td>\n",
       "      <td>47.550000</td>\n",
       "      <td>0.630662</td>\n",
       "      <td>0.0</td>\n",
       "      <td>15.006088</td>\n",
       "      <td>19.446782</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>34.452870</td>\n",
       "      <td>D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>998</th>\n",
       "      <td>998</td>\n",
       "      <td>3313.852194</td>\n",
       "      <td>0.293604</td>\n",
       "      <td>164</td>\n",
       "      <td>32</td>\n",
       "      <td>47.416667</td>\n",
       "      <td>0.627053</td>\n",
       "      <td>0.0</td>\n",
       "      <td>15.051077</td>\n",
       "      <td>19.517178</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>34.568255</td>\n",
       "      <td>D</td>\n",
       "    </tr>\n",
       "    <tr>\n",
       "      <th>999</th>\n",
       "      <td>999</td>\n",
       "      <td>3352.945938</td>\n",
       "      <td>0.290233</td>\n",
       "      <td>192</td>\n",
       "      <td>31</td>\n",
       "      <td>47.666667</td>\n",
       "      <td>0.632256</td>\n",
       "      <td>0.0</td>\n",
       "      <td>14.273692</td>\n",
       "      <td>19.537720</td>\n",
       "      <td>0</td>\n",
       "      <td>0.0</td>\n",
       "      <td>33.811412</td>\n",
       "      <td>D</td>\n",
       "    </tr>\n",
       "  </tbody>\n",
       "</table>\n",
       "<p>1000 rows × 14 columns</p>\n",
       "</div>"
      ],
      "text/plain": [
       "     vehicle_id  total_distance  overspeed_rate  hard_brake_count  \\\n",
       "0             0     3386.560282        0.309474               196   \n",
       "1             1     3309.030614        0.291117               185   \n",
       "2             2     3331.436376        0.305410               214   \n",
       "3             3     3336.086285        0.295936               166   \n",
       "4             4     3393.379616        0.314207               182   \n",
       "..          ...             ...             ...               ...   \n",
       "995         995     3342.214145        0.292029               179   \n",
       "996         996     3356.451499        0.299166               178   \n",
       "997         997     3344.071826        0.310453               167   \n",
       "998         998     3313.852194        0.293604               164   \n",
       "999         999     3352.945938        0.290233               192   \n",
       "\n",
       "     sharp_turn_count  fatigue_hours  high_risk_time_ratio  speed_score  \\\n",
       "0                  38      47.933333              0.629668          0.0   \n",
       "1                  30      47.766667              0.631506          0.0   \n",
       "2                  29      47.466667              0.627923          0.0   \n",
       "3                  36      47.733333              0.628691          0.0   \n",
       "4                  29      47.933333              0.630833          0.0   \n",
       "..                ...            ...                   ...          ...   \n",
       "995                35      47.600000              0.633484          0.0   \n",
       "996                41      47.700000              0.630299          0.0   \n",
       "997                37      47.550000              0.630662          0.0   \n",
       "998                32      47.416667              0.627053          0.0   \n",
       "999                31      47.666667              0.632256          0.0   \n",
       "\n",
       "     brake_score  turn_score  fatigue_score  time_score  driver_score  \\\n",
       "0      14.212417   19.438959              0         0.0     33.651375   \n",
       "1      14.409239   19.546695              0         0.0     33.955934   \n",
       "2      13.576344   19.564752              0         0.0     33.141097   \n",
       "3      15.024110   19.460446              0         0.0     34.484555   \n",
       "4      14.636615   19.572697              0         0.0     34.209313   \n",
       "..           ...         ...            ...         ...           ...   \n",
       "995    14.644269   19.476395              0         0.0     34.120664   \n",
       "996    14.696780   19.389236              0         0.0     34.086016   \n",
       "997    15.006088   19.446782              0         0.0     34.452870   \n",
       "998    15.051077   19.517178              0         0.0     34.568255   \n",
       "999    14.273692   19.537720              0         0.0     33.811412   \n",
       "\n",
       "    risk_rating  \n",
       "0             D  \n",
       "1             D  \n",
       "2             D  \n",
       "3             D  \n",
       "4             D  \n",
       "..          ...  \n",
       "995           D  \n",
       "996           D  \n",
       "997           D  \n",
       "998           D  \n",
       "999           D  \n",
       "\n",
       "[1000 rows x 14 columns]"
      ]
     },
     "execution_count": 13,
     "metadata": {},
     "output_type": "execute_result"
    }
   ],
   "source": [
    "driver_scores"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "9de3fe2a-b9ef-49e6-988f-4674b9ec8436",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": 14,
   "id": "5f3593ff-25c1-4587-9961-8591785bfbce",
   "metadata": {},
   "outputs": [
    {
     "ename": "TypeError",
     "evalue": "unsupported operand type(s) for *: 'int' and 'Categorical'",
     "output_type": "error",
     "traceback": [
      "\u001b[31m---------------------------------------------------------------------------\u001b[39m",
      "\u001b[31mTypeError\u001b[39m                                 Traceback (most recent call last)",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[14]\u001b[39m\u001b[32m, line 21\u001b[39m\n\u001b[32m     18\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m driver_scores\n\u001b[32m     20\u001b[39m \u001b[38;5;66;03m# 执行UBI模型\u001b[39;00m\n\u001b[32m---> \u001b[39m\u001b[32m21\u001b[39m insurance_data = \u001b[43mubi_insurance_model\u001b[49m\u001b[43m(\u001b[49m\u001b[43mdriver_scores\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mCell\u001b[39m\u001b[36m \u001b[39m\u001b[32mIn[14]\u001b[39m\u001b[32m, line 12\u001b[39m, in \u001b[36mubi_insurance_model\u001b[39m\u001b[34m(driver_scores)\u001b[39m\n\u001b[32m     10\u001b[39m \u001b[38;5;66;03m# 计算调整后的保费\u001b[39;00m\n\u001b[32m     11\u001b[39m driver_scores[\u001b[33m\"\u001b[39m\u001b[33mrisk_coeff\u001b[39m\u001b[33m\"\u001b[39m] = driver_scores[\u001b[33m\"\u001b[39m\u001b[33mrisk_rating\u001b[39m\u001b[33m\"\u001b[39m].map(risk_coefficient)\n\u001b[32m---> \u001b[39m\u001b[32m12\u001b[39m driver_scores[\u001b[33m\"\u001b[39m\u001b[33mpremium\u001b[39m\u001b[33m\"\u001b[39m] = \u001b[43mbase_premium\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m \u001b[49m\u001b[43mdriver_scores\u001b[49m\u001b[43m[\u001b[49m\u001b[33;43m\"\u001b[39;49m\u001b[33;43mrisk_coeff\u001b[39;49m\u001b[33;43m\"\u001b[39;49m\u001b[43m]\u001b[49m\n\u001b[32m     14\u001b[39m \u001b[38;5;66;03m# 计算预期赔付率 (基于历史数据)\u001b[39;00m\n\u001b[32m     15\u001b[39m claim_rates = {\u001b[33m'\u001b[39m\u001b[33mA\u001b[39m\u001b[33m'\u001b[39m: \u001b[32m0.05\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mB\u001b[39m\u001b[33m'\u001b[39m: \u001b[32m0.08\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mC\u001b[39m\u001b[33m'\u001b[39m: \u001b[32m0.15\u001b[39m, \u001b[33m'\u001b[39m\u001b[33mD\u001b[39m\u001b[33m'\u001b[39m: \u001b[32m0.25\u001b[39m}\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/py3.13/lib/python3.13/site-packages/pandas/core/ops/common.py:76\u001b[39m, in \u001b[36m_unpack_zerodim_and_defer.<locals>.new_method\u001b[39m\u001b[34m(self, other)\u001b[39m\n\u001b[32m     72\u001b[39m             \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mNotImplemented\u001b[39m\n\u001b[32m     74\u001b[39m other = item_from_zerodim(other)\n\u001b[32m---> \u001b[39m\u001b[32m76\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mmethod\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mother\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/py3.13/lib/python3.13/site-packages/pandas/core/arraylike.py:206\u001b[39m, in \u001b[36mOpsMixin.__rmul__\u001b[39m\u001b[34m(self, other)\u001b[39m\n\u001b[32m    204\u001b[39m \u001b[38;5;129m@unpack_zerodim_and_defer\u001b[39m(\u001b[33m\"\u001b[39m\u001b[33m__rmul__\u001b[39m\u001b[33m\"\u001b[39m)\n\u001b[32m    205\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m__rmul__\u001b[39m(\u001b[38;5;28mself\u001b[39m, other):\n\u001b[32m--> \u001b[39m\u001b[32m206\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28;43mself\u001b[39;49m\u001b[43m.\u001b[49m\u001b[43m_arith_method\u001b[49m\u001b[43m(\u001b[49m\u001b[43mother\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mroperator\u001b[49m\u001b[43m.\u001b[49m\u001b[43mrmul\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/py3.13/lib/python3.13/site-packages/pandas/core/series.py:6135\u001b[39m, in \u001b[36mSeries._arith_method\u001b[39m\u001b[34m(self, other, op)\u001b[39m\n\u001b[32m   6133\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34m_arith_method\u001b[39m(\u001b[38;5;28mself\u001b[39m, other, op):\n\u001b[32m   6134\u001b[39m     \u001b[38;5;28mself\u001b[39m, other = \u001b[38;5;28mself\u001b[39m._align_for_op(other)\n\u001b[32m-> \u001b[39m\u001b[32m6135\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mbase\u001b[49m\u001b[43m.\u001b[49m\u001b[43mIndexOpsMixin\u001b[49m\u001b[43m.\u001b[49m\u001b[43m_arith_method\u001b[49m\u001b[43m(\u001b[49m\u001b[38;5;28;43mself\u001b[39;49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mother\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mop\u001b[49m\u001b[43m)\u001b[49m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/py3.13/lib/python3.13/site-packages/pandas/core/base.py:1382\u001b[39m, in \u001b[36mIndexOpsMixin._arith_method\u001b[39m\u001b[34m(self, other, op)\u001b[39m\n\u001b[32m   1379\u001b[39m     rvalues = np.arange(rvalues.start, rvalues.stop, rvalues.step)\n\u001b[32m   1381\u001b[39m \u001b[38;5;28;01mwith\u001b[39;00m np.errstate(\u001b[38;5;28mall\u001b[39m=\u001b[33m\"\u001b[39m\u001b[33mignore\u001b[39m\u001b[33m\"\u001b[39m):\n\u001b[32m-> \u001b[39m\u001b[32m1382\u001b[39m     result = \u001b[43mops\u001b[49m\u001b[43m.\u001b[49m\u001b[43marithmetic_op\u001b[49m\u001b[43m(\u001b[49m\u001b[43mlvalues\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mrvalues\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mop\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m   1384\u001b[39m \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[38;5;28mself\u001b[39m._construct_result(result, name=res_name)\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/py3.13/lib/python3.13/site-packages/pandas/core/ops/array_ops.py:273\u001b[39m, in \u001b[36marithmetic_op\u001b[39m\u001b[34m(left, right, op)\u001b[39m\n\u001b[32m    260\u001b[39m \u001b[38;5;66;03m# NB: We assume that extract_array and ensure_wrapped_if_datetimelike\u001b[39;00m\n\u001b[32m    261\u001b[39m \u001b[38;5;66;03m#  have already been called on `left` and `right`,\u001b[39;00m\n\u001b[32m    262\u001b[39m \u001b[38;5;66;03m#  and `maybe_prepare_scalar_for_op` has already been called on `right`\u001b[39;00m\n\u001b[32m    263\u001b[39m \u001b[38;5;66;03m# We need to special-case datetime64/timedelta64 dtypes (e.g. because numpy\u001b[39;00m\n\u001b[32m    264\u001b[39m \u001b[38;5;66;03m# casts integer dtypes to timedelta64 when operating with timedelta64 - GH#22390)\u001b[39;00m\n\u001b[32m    266\u001b[39m \u001b[38;5;28;01mif\u001b[39;00m (\n\u001b[32m    267\u001b[39m     should_extension_dispatch(left, right)\n\u001b[32m    268\u001b[39m     \u001b[38;5;129;01mor\u001b[39;00m \u001b[38;5;28misinstance\u001b[39m(right, (Timedelta, BaseOffset, Timestamp))\n\u001b[32m   (...)\u001b[39m\u001b[32m    271\u001b[39m     \u001b[38;5;66;03m# Timedelta/Timestamp and other custom scalars are included in the check\u001b[39;00m\n\u001b[32m    272\u001b[39m     \u001b[38;5;66;03m# because numexpr will fail on it, see GH#31457\u001b[39;00m\n\u001b[32m--> \u001b[39m\u001b[32m273\u001b[39m     res_values = \u001b[43mop\u001b[49m\u001b[43m(\u001b[49m\u001b[43mleft\u001b[49m\u001b[43m,\u001b[49m\u001b[43m \u001b[49m\u001b[43mright\u001b[49m\u001b[43m)\u001b[49m\n\u001b[32m    274\u001b[39m \u001b[38;5;28;01melse\u001b[39;00m:\n\u001b[32m    275\u001b[39m     \u001b[38;5;66;03m# TODO we should handle EAs consistently and move this check before the if/else\u001b[39;00m\n\u001b[32m    276\u001b[39m     \u001b[38;5;66;03m# (https://github.com/pandas-dev/pandas/issues/41165)\u001b[39;00m\n\u001b[32m    277\u001b[39m     \u001b[38;5;66;03m# error: Argument 2 to \"_bool_arith_check\" has incompatible type\u001b[39;00m\n\u001b[32m    278\u001b[39m     \u001b[38;5;66;03m# \"Union[ExtensionArray, ndarray[Any, Any]]\"; expected \"ndarray[Any, Any]\"\u001b[39;00m\n\u001b[32m    279\u001b[39m     _bool_arith_check(op, left, right)  \u001b[38;5;66;03m# type: ignore[arg-type]\u001b[39;00m\n",
      "\u001b[36mFile \u001b[39m\u001b[32m~/miniconda3/envs/py3.13/lib/python3.13/site-packages/pandas/core/roperator.py:19\u001b[39m, in \u001b[36mrmul\u001b[39m\u001b[34m(left, right)\u001b[39m\n\u001b[32m     18\u001b[39m \u001b[38;5;28;01mdef\u001b[39;00m\u001b[38;5;250m \u001b[39m\u001b[34mrmul\u001b[39m(left, right):\n\u001b[32m---> \u001b[39m\u001b[32m19\u001b[39m     \u001b[38;5;28;01mreturn\u001b[39;00m \u001b[43mright\u001b[49m\u001b[43m \u001b[49m\u001b[43m*\u001b[49m\u001b[43m \u001b[49m\u001b[43mleft\u001b[49m\n",
      "\u001b[31mTypeError\u001b[39m: unsupported operand type(s) for *: 'int' and 'Categorical'"
     ]
    }
   ],
   "source": [
    "\n",
    "# ========== UBI保险模型 ==========\n",
    "def ubi_insurance_model(driver_scores):\n",
    "    \"\"\"UBI保险定价模型\"\"\"\n",
    "    # 基础保费\n",
    "    base_premium = 5000\n",
    "    \n",
    "    # 风险系数映射\n",
    "    risk_coefficient = {'A': 0.8, 'B': 1.0, 'C': 1.3, 'D': 1.8}\n",
    "    \n",
    "    # 计算调整后的保费\n",
    "    driver_scores[\"risk_coeff\"] = driver_scores[\"risk_rating\"].map(risk_coefficient)\n",
    "    driver_scores[\"premium\"] = base_premium * driver_scores[\"risk_coeff\"]\n",
    "    \n",
    "    # 计算预期赔付率 (基于历史数据)\n",
    "    claim_rates = {'A': 0.05, 'B': 0.08, 'C': 0.15, 'D': 0.25}\n",
    "    driver_scores[\"expected_claim_rate\"] = driver_scores[\"risk_rating\"].map(claim_rates)\n",
    "    \n",
    "    return driver_scores\n",
    "\n",
    "# 执行UBI模型\n",
    "insurance_data = ubi_insurance_model(driver_scores)"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "69b15768-53c3-4bfe-a64a-bdd6ffc8e266",
   "metadata": {},
   "outputs": [],
   "source": [
    "insurance_data"
   ]
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "aa61fcc4-da94-4518-8d5b-28e373263c59",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "da6d73e1-f021-4fc2-9fe6-f1971e2986c1",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "ce49ca34-5c79-42b9-91f3-0fa06135fb2d",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c1eba0bf-9e97-4ec2-a915-9d9b45fad982",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "c1a3192c-ca8a-426f-8160-11a71b6649bf",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "f7382859-da46-48ec-b2a1-6511c8f89bb5",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "d6556c9a-0f60-48de-a123-b65ce14e3571",
   "metadata": {},
   "outputs": [],
   "source": []
  },
  {
   "cell_type": "code",
   "execution_count": null,
   "id": "477c945f-a50a-407e-aa4a-6f443bb86c7f",
   "metadata": {},
   "outputs": [],
   "source": []
  }
 ],
 "metadata": {
  "kernelspec": {
   "display_name": "Python 3 (ipykernel)",
   "language": "python",
   "name": "python3"
  },
  "language_info": {
   "codemirror_mode": {
    "name": "ipython",
    "version": 3
   },
   "file_extension": ".py",
   "mimetype": "text/x-python",
   "name": "python",
   "nbconvert_exporter": "python",
   "pygments_lexer": "ipython3",
   "version": "3.13.2"
  }
 },
 "nbformat": 4,
 "nbformat_minor": 5
}
